/**
 * 工具函数
 * @author 一生为倾狂
 * @time 2018-07-23
 */

// 判断是否是表单对象
export function isFormData(data: any) {
  return Object.prototype.toString.call(data) === '[object FormData]';
}

export function timeFix() {
  const time = new Date()
  const hour = time.getHours()
  return hour < 9 ? '早上好' : hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好'
}

/**
 * 统一处理async await错误
 *
 * @export
 * @param {Promise<any[]>} promise
 * @returns {Promise<any[]>}
 */
export function to(promise: Promise<any[]>): Promise<any[]> {
  return promise.then((data: any) => {
    return [null, data];
  })
    .catch((err: any) => [err]);
}

/**
 * 获取get参数
 *
 * @param {string} name 参数名
 * @param {string} [mode='hash'] 获取模式 hash 和正常模式
 * @returns
 */
export const getQueryString = (name: string, mode: string = 'hash') => {
  let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
  const str = mode === 'hash' ? window.location.hash.split('?')[1] : window.location.search.substr(1)
  if (!str) return null
  let r = str.match(reg);
  if (r != null) return unescape(r[2]); return null;
}

/**
 * 格式化二维数组为树形结构
 * @param data {array} 二位数组
 * @param options {object} 配置参数
 * @param --parentId {string} 父级Id键名
 * @param --id {string} id 自身Id键名
 * @param --children {string} 子集键名
 * {
 *  parentId: 'parentId',
 *  id: 'id',
 *  children: 'children'
 * }
 * @return arr {array} 格式化之后的数组
 */
export interface FormatTreeOptions {
  parentId?: string,
  id?: string,
  childrens?: string
}
export function formatTree(data: any[], options?: FormatTreeOptions, isChild: boolean = false) {
  if (Object.prototype.toString.call(data) !== '[object Array]') {
    throw new Error(`formatTree - data：不是一个数组`);
  }

  // 配置项
  const defaultOptions = Object.assign(
    {
      parentId: 'parentId',
      id: 'id',
      childrens: 'children',
    },
    options,
  );

  const { parentId, id, childrens } = defaultOptions;
  const arr: any = [];

  let map: Record<string, any> = {};

  console.time('map')
  for (let i = 0; i < data.length; i++) {
    let item = data[i];
    map[item[id]] = item;
  }
  console.timeEnd('map')

  // console.time('forin')
  // for (let key in map) {
  //   let item = map[key]
  //   if (!item[parentId] || !map[item[parentId]]) {
  //     const o = formatData(item, data);
  //     arr.push(o);
  //   }
  // }
  // console.timeEnd('forin')

  for (let i = 0; i < data.length; i++) {
    let item = data[i];
    if (!item[parentId] || !map[item[parentId]]) {
      data.splice(i, 1)
      i--;
      const o = formatData(item, data);
      arr.push(o);
    }
  }

  // data.forEach((item: any) => {
  //   if (!item[parentId] || !data.some((items: any) => items[id] === item[parentId])) {
  //     const o = formatData(item, data);
  //     arr.push(o);
  //   }
  // });

  function formatData(obj: any, arr: any[]) {
    const children: any = [];
    
    for (let i = 0; i < arr.length; i++) {
      let item = arr[i];
      if (item[parentId] === obj[id]) {
        // arr.splice(i, 1);
        // i--;
        formatData(item, arr);
        children.push(item);
      }
    }
    if (children.length) {
      obj[childrens] = children;
    } else {
      if (isChild) {
        obj[childrens] = []
      }
    }

    return obj;
  }

  return arr;
}

export function formatDate(time: any, format = 'YYYY-MM-DD hh:mm:ss') {
  const date = new Date(time);

  const year: any = date.getFullYear();
  const month = date.getMonth() + 1; // 月份是从0开始的
  const day = date.getDate();
  const hour = date.getHours();
  const min = date.getMinutes();
  const sec = date.getSeconds();
  let preArr: any = Array.apply(null, Array(10)).map((elem: any, index: number) => {
    return '0' + index;
  }); // 开个长度为10的数组 格式为 00 01 02 03

  const newTime = format.replace(/YYYY/g, year)
    .replace(/MM/g, preArr[month] || month)
    .replace(/DD/g, preArr[day] || day)
    .replace(/hh/g, preArr[hour] || hour)
    .replace(/mm/g, preArr[min] || min)
    .replace(/ss/g, preArr[sec] || sec);

  return newTime;
}

// scrollTop animation
export function scrollTo(el: any, from = 0, to: any, duration = 500, direction = 'top') {
  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame =
    // @ts-ignore
      window.webkitRequestAnimationFrame ||
      // window.mozRequestAnimationFrame ||
      // window.msRequestAnimationFrame ||
      ((callback) => {
        return window.setTimeout(callback, 1000 / 60);
      });
  }
  const difference = Math.abs(from - to);
  const step = Math.ceil((difference / duration) * 5);

  function scroll(start: any, end: any, step: any) {
    if (start === end) return;

    let d = start + step > end ? end : start + step;
    if (start > end) {
      d = start - step < end ? end : start - step;
    }

    if (el === window) {
      window.scrollTo(d, d);
    } else {
      el['scroll' + titleCase(direction)] = d;
    }
    window.requestAnimationFrame(() => scroll(d, end, step));
  }
  scroll(from, to, step);
}

export function titleCase(str: string) {
  return str.substr(0, 1).toUpperCase() + str.substr(1);
}

export function assert(condition: any, msg: any) {
  if (!condition) throw new Error(`[Apior] ${msg}`);
}

export function getCheckedChartGroup(data: any) {
  let arr: any = [];
  if (data && data.length > 0) {
    arr.push(data[0].group_field);
    if (data[0].views && data[0].views.length > 0) {
      arr.push(data[0].views[0].chart_name);
    }
  }
  return arr;
}

/**
 * 解析url参数
 * @example ?id=12345&a=b
 * @return Object {id:12345,a:b}
 */
export function urlParse(url: string) {
  let obj: any = {};
  let reg = /[?&][^?&]+=[^?&]+/g;
  let arr = url.match(reg);
  // ['?id=12345', '&a=b']
  if (arr) {
    arr.forEach((item) => {
      let tempArr = item.substring(1).split('=');
      let key = decodeURIComponent(tempArr[0]);
      let val = decodeURIComponent(tempArr[1]);
      obj[key] = val;
    });
  }
  return obj;
};

/**
 * base64转blob
 *
 * @param {string} dataurl
 * @returns
 */
export function dataURLtoBlob(dataurl: string) {
  let arr = dataurl.split(',')
  let mime = arr[0] && arr[0].match(/:(.*?);/);
  let bstr = atob(arr[1])
  let n = bstr.length
  let u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime ? mime[1] : '' });
}

/**
 * 判断身份证是否有效
 *
 * @export
 * @param {string} str
 * @returns
 */
export function isIDCard(str: string) {
  return /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(str)
}